/********************************************************************************
    Author :
********************************************************************************/

/********************************************************************************
    Include Files :
********************************************************************************/
#include "extern.h"
	#include "Light.h"
	#include "Button.h"
    #include "IoHwAb.h"

#include "alloc.h"
    #include "App.h"
/********************************************************************************
    Defination :
********************************************************************************/

/********************************************************************************
    Comment : The timer counter about lock button and switch light
********************************************************************************/
#define u8_LOCK_COUNTER         (uint8)30
#define u8_UNLOCK_COUNTER       (uint8)50
#define u8_SWITCH_COUNTER       (uint8)10
#define u8_COUNTER_RESET        (uint8)0
#define u8_MAX_COUNTER          (uint8)0xFF

/********************************************************************************
    Comment : The timer counter about state machine
********************************************************************************/
#define u8_ON_COUNTER       (uint8)20
#define u8_OFF_COUNTER      (uint8)20
#define u8_ON_OFF_COUNTER   (uint8)20
#define u8_OFF_ON_COUNTER   (uint8)20
#define u8_TIME_OUT         (uint8)0
#define u8_CHANGE_CYCLE     (uint8)4
/********************************************************************************
    Type name :
********************************************************************************/

/********************************************************************************
    Comment : The description of type name
********************************************************************************/
typedef enum
{
    ENU_DEFAULE = (uint8)0x00, 
    ENU_OFF     = (uint8)0x01, 
    ENU_ON      = (uint8)0x02, 
    ENU_OFF_ON  = (uint8)0x03, 
    ENU_ON_OFF  = (uint8)0x04,
    ENU_STOP    = (uint8)0x05,
}enuMainState;

/********************************************************************************
    Private variables :
********************************************************************************/

/********************************************************************************
    Comment : The selected light
********************************************************************************/
PRIVATE enuSelectLight enuSelectedLight = ENU_SELECT_LIGHT_RED;

/********************************************************************************
    Comment : The button status is locked or not
********************************************************************************/
PRIVATE boolean bIsLock = TRUE;

/********************************************************************************
    Comment : The counter of lock,unlock and swtich light
********************************************************************************/
PRIVATE uint8 u8LockCounter   = u8_COUNTER_RESET;
PRIVATE uint8 uUnlockCounter  = u8_COUNTER_RESET;
PRIVATE uint8 u8SwitchCounter = u8_COUNTER_RESET;

/********************************************************************************
    Comment : Check if it is time out
********************************************************************************/
PRIVATE boolean b100msTimeout = FALSE;
PRIVATE boolean b10msTimeout = FALSE;

/********************************************************************************
    Comment : Check if it is time out
********************************************************************************/
PRIVATE uint8 u8StateMachineTimer = u8_TIME_OUT;

/********************************************************************************
    Comment : The state of state machine
********************************************************************************/
PRIVATE enuMainState enuMachineState = ENU_DEFAULE;

/********************************************************************************
    Comment : The change cycle of brightness
********************************************************************************/
PRIVATE uint8 u8ChangeCycle = u8_TIME_OUT;

/********************************************************************************
    Comment : Check if button is pressed in this cycle
********************************************************************************/
PRIVATE boolean bButton1Press = FALSE;
PRIVATE boolean bButton2Press = FALSE;

/********************************************************************************
    Private function declaration :
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidTimeout(void);
PRIVATE FUNC(void,APP_CODE) vidClearFlag(void);
PRIVATE FUNC(void,APP_CODE) vidUpdateSelectLight(void);
PRIVATE FUNC(void,APP_CODE) vidUpdateLockStatus(void);
PRIVATE FUNC(void,APP_CODE) vidUpdateBrightness(void);
PRIVATE FUNC(void,APP_CODE) vidUpdateBrightnessByAdc(void);
PRIVATE FUNC(void,APP_CODE) vidButtonInterrupt(void);
PRIVATE FUNC(void,APP_CODE) vidClearInterruptFlag(void);
PRIVATE FUNC(void,APP_CODE) vidMainStatemachine(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuDefaultAction(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuOnAction(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuOffAction(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuOffToOnAction(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuOnToOffAction(void);
PRIVATE FUNC(enuMainState,APP_CODE) enuStopAction(void);
/********************************************************************************
    Public function :
********************************************************************************/

/********************************************************************************
    Description :
        Main function
********************************************************************************/
PUBLIC FUNC(void,APP_CODE) App_vidMainFunction(void)
{
	vidTimeout();

    vidButtonInterrupt();

    vidUpdateSelectLight();
    vidUpdateLockStatus();
    vidUpdateBrightness();
    vidUpdateBrightnessByAdc();
    if(bIsLock == TRUE)
    {
        vidMainStatemachine();
    }
    else
    {
        Light_vidUpdateLockLight(TRUE);
    }

    vidClearInterruptFlag();
    vidClearFlag();
}

/********************************************************************************
    Description :
        Initial function
********************************************************************************/
PUBLIC FUNC(void,APP_CODE) App_vidInitFunction(void)
{
    IoHwAb_vidInitFunction();
}

/********************************************************************************
    Private function :
********************************************************************************/
/********************************************************************************
    Description :
        Check if it is time out
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidTimeout(void)
{
    b10msTimeout = IoHwAb_b10msTimeout();
    b100msTimeout = IoHwAb_b100msTimeout();
}

/********************************************************************************
    Description :
        Clear timer flag
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidClearFlag(void)
{
    if(b10msTimeout ==TRUE)
    {
        IoHwAb_vidClear10msTimerFlag();
    }
    else
    {
        
    }
    
    if(b100msTimeout ==TRUE)
    {
        IoHwAb_vidClear100msTimerFlag();
    }
    else
    {
        
    }
}

/********************************************************************************
    Description :
        Button3 : Select light to control by button
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidUpdateSelectLight(void)
{
	boolean bLockButtonPress = FALSE;
    bLockButtonPress = Button_bIsPress(ENU_LOCK_BUTTON);
    if(bLockButtonPress == TRUE)
    {
        if(u8SwitchCounter < u8_MAX_COUNTER && b100msTimeout == TRUE)
        {
            u8SwitchCounter++;
        }
        else
        {

        }        
    }
    else
    {
        u8SwitchCounter = u8_COUNTER_RESET;
    }

    if(u8SwitchCounter == u8_SWITCH_COUNTER )
    {
    	u8SwitchCounter = u8_COUNTER_RESET;
       if(enuSelectedLight == ENU_SELECT_LIGHT_RED)
       {
            enuSelectedLight = ENU_SELECT_LIGHT_GREEN;
            Light_vidSetBrightness(ENU_SELECT_LIGHT_GREEN,ENU_LEVEL_ON);
       }
       else
       {
            enuSelectedLight = ENU_SELECT_LIGHT_RED;
            Light_vidSetBrightness(ENU_SELECT_LIGHT_RED,ENU_LEVEL_ON);
       }

       Light_vidSetSelectLight(enuSelectedLight);
       
    }
    else
    {
        
    }
}

/********************************************************************************
    Description :
        Button3 : Lock and Unlock
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidUpdateLockStatus(void)
{
    boolean bButton3Press = FALSE;
    bButton3Press = Button_bIsPress(ENU_LOCK_BUTTON);
    if(bIsLock == TRUE)
    {
        if(bButton3Press == TRUE)
        {
            if(u8LockCounter < u8_MAX_COUNTER && b100msTimeout == TRUE)
            {
                u8LockCounter++;
            }
            else
            {
                
            } 
        }
        else
        {
            u8LockCounter = u8_COUNTER_RESET;
        }

        if(u8LockCounter == u8_UNLOCK_COUNTER)
        {
        	u8LockCounter = u8_COUNTER_RESET;
            bIsLock = FALSE;
            Light_vidUpdateLockLight(FALSE);
        }
        else
        {
            
        }
    }
    else
    {
        if(bButton3Press == TRUE)
        {
            if(uUnlockCounter < u8_MAX_COUNTER && b100msTimeout == TRUE)
            {
                uUnlockCounter++;
            }
            else
            {
                
            } 
        }
        else
        {
            uUnlockCounter = u8_COUNTER_RESET;
        }
        if(uUnlockCounter == u8_LOCK_COUNTER)
        {
         	uUnlockCounter = u8_COUNTER_RESET;
            bIsLock = TRUE;
            Light_vidUpdateLockLight(TRUE);
        }
        else
        {
            
        }
    }
    
}

/********************************************************************************
    Description :
        Update brightness by button
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidUpdateBrightness(void)
{
    if (enuSelectedLight == ENU_SELECT_LIGHT_RED)
    {

        if(bButton1Press == TRUE && bIsLock == FALSE)
        {
            Light_vidDecreaseBrightness(ENU_SELECT_LIGHT_RED);
        }
        else
        {
            
        }
        if(bButton2Press == TRUE && bIsLock == FALSE)
        {
            Light_vidIncreaseBrightness(ENU_SELECT_LIGHT_RED);
        }
        else
        {
            
        } 
    }
    else if (enuSelectedLight == ENU_SELECT_LIGHT_GREEN)
    {
        if(bButton1Press == TRUE && bIsLock == FALSE)
        {
            Light_vidDecreaseBrightness(ENU_SELECT_LIGHT_GREEN);
        }
        else
        {
            
        }
        if(bButton2Press == TRUE && bIsLock == FALSE)
        {
            Light_vidIncreaseBrightness(ENU_SELECT_LIGHT_GREEN);
        }
        else
        {
            
        } 
    }
    else
    {

    }
}

/********************************************************************************
    Description :
        Update brightness by Adc
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidUpdateBrightnessByAdc(void)
{
    if(enuSelectedLight == ENU_SELECT_LIGHT_RED)
    {
        Light_vidSetAdcValue(ENU_SELECT_LIGHT_GREEN);
    }
    else if (enuSelectedLight == ENU_SELECT_LIGHT_GREEN)
    {
        Light_vidSetAdcValue(ENU_SELECT_LIGHT_RED);
    }
    else
    {
        
    }
}

/********************************************************************************
    Description :
        There is an interrupt in this cycle or not
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidButtonInterrupt(void)
{
    boolean bButton1Interrupt = FALSE;
    boolean bButton2Interrupt = FALSE;
    bButton1Interrupt = Button_bIsButton1Trigger();
    bButton2Interrupt = Button_bIsButton2Trigger();
    if(bButton1Interrupt == TRUE)
    {
        bButton1Press = TRUE;
    }
    else
    {
        
    }
    if(bButton2Interrupt == TRUE)
    {
        bButton2Press = TRUE;
    }
    else
    {
        
    }
}

/********************************************************************************
    Description :
        Clear flag of interrupt
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidClearInterruptFlag(void)
{
    bButton1Press = FALSE;
    bButton2Press = FALSE;
}
/********************************************************************************
    Description :
        The main state machine of lock light
********************************************************************************/
PRIVATE FUNC(void,APP_CODE) vidMainStatemachine(void)
{
    switch (enuMachineState)
    {
        case ENU_STOP:
        enuMachineState = enuStopAction();
            break;
        case ENU_DEFAULE:
        enuMachineState = enuDefaultAction();
            break;
        case ENU_ON:
        enuMachineState = enuOnAction();
            break;
        case ENU_OFF:
        enuMachineState = enuOffAction();
            break;
        case ENU_OFF_ON:
        enuMachineState = enuOffToOnAction();
            break;
        case ENU_ON_OFF:
        enuMachineState = enuOnToOffAction();
            break;
        default:
            break;
    }
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuDefaultAction(void)
{
    enuMainState enuNextState = ENU_ON;
    u8ChangeCycle = u8_TIME_OUT;
    u8StateMachineTimer = u8_TIME_OUT;
    return enuNextState;
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuOnAction(void)
{
    enuMainState enuNextState = ENU_ON;
    if(u8StateMachineTimer > u8_TIME_OUT && b100msTimeout == TRUE)
    {
        u8StateMachineTimer--;
    }
    else
    {
        
    }
    if(u8StateMachineTimer == u8_TIME_OUT)
    {
        u8StateMachineTimer = u8_ON_OFF_COUNTER;
        enuNextState = ENU_ON_OFF;
    }
    else
    {
        enuNextState = ENU_ON;
    }

    if(bButton1Press == TRUE || bButton2Press == TRUE)
    {
    	Light_vidSetBrightness(ENU_LOCK_LGIHT,ENU_LEVEL_OFF);
        u8StateMachineTimer = u8_ON_COUNTER;
        enuNextState = ENU_ON;
    }
    else
    {
        
    }
    return enuNextState;
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuOffAction(void)
{
    enuMainState enuNextState = ENU_OFF;
    if(bButton1Press == TRUE || bButton2Press == TRUE)
    {
        u8StateMachineTimer = u8_OFF_ON_COUNTER;
        enuNextState = ENU_OFF_ON;
    }
    else
    {
        
    }

    return enuNextState;
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuOffToOnAction(void)
{
    enuMainState enuNextState = ENU_OFF_ON;
    if(u8StateMachineTimer > u8_TIME_OUT && b100msTimeout == TRUE)
    {
        u8StateMachineTimer--;
        u8ChangeCycle++;
    }
    else
    {
        
    }
    if(u8ChangeCycle == u8_CHANGE_CYCLE)
    {
        Light_vidIncreaseBrightness(ENU_LOCK_LGIHT);
        u8ChangeCycle = u8_TIME_OUT;
    }
    else
    {
        
    }
    if(u8StateMachineTimer == u8_TIME_OUT)
    {
        enuNextState = ENU_ON;
    }
    else
    {
        enuNextState = ENU_OFF_ON;
    }

    if(bButton1Press == TRUE || bButton2Press == TRUE)
    {
    	Light_vidSetBrightness(ENU_LOCK_LGIHT,ENU_LEVEL_OFF);
        u8StateMachineTimer = u8_ON_COUNTER;
        enuNextState = ENU_ON;
    }
    else
    {
        
    }
    return enuNextState;
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuOnToOffAction(void)
{
    enuMainState enuNextState = ENU_ON_OFF;
    if(u8StateMachineTimer > u8_TIME_OUT && b100msTimeout == TRUE)
    {
        u8StateMachineTimer--;
        u8ChangeCycle++;
    }
    else
    {
        
    }
    if(u8ChangeCycle == u8_CHANGE_CYCLE)
    {
        Light_vidDecreaseBrightness(ENU_LOCK_LGIHT);
        u8ChangeCycle = u8_TIME_OUT;
    }
    else
    {
        
    }
    if(u8StateMachineTimer == u8_TIME_OUT)
    {
        enuNextState = ENU_OFF;
    }
    else
    {
        enuNextState = ENU_ON_OFF;
    }

    if(bButton1Press == TRUE || bButton2Press == TRUE)
    {
    	Light_vidSetBrightness(ENU_LOCK_LGIHT,ENU_LEVEL_OFF);
        u8StateMachineTimer = u8_ON_COUNTER;
        enuNextState = ENU_ON;
    }
    else
    {
        
    }
    return enuNextState;
}

/********************************************************************************
    Description :
        The default state in main state machine
********************************************************************************/
PRIVATE FUNC(enuMainState,APP_CODE) enuStopAction(void)
{
    enuMainState enuNextState = ENU_STOP;
    boolean bButton1Press = FALSE, bButton2Press = FALSE;
    bButton1Press = Button_bIsButton1Trigger();
    bButton2Press = Button_bIsButton2Trigger();
    if(bButton1Press || bButton2Press)
    {
        enuNextState = ENU_DEFAULE;
    }
    else
    {
        enuNextState = ENU_STOP;
    }
    return enuNextState;
}


